package baseFx.tests.database.mybatis;

import baseFx.common.utils.ResourceUtils;
import baseFx.database.mybatis.MybatisContext;
import baseFx.database.mybatis.MybatisSql;
import baseFx.database.mybatis.impl.MysqlSql;
import baseFx.database.query.PageSet;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.junit.Test;
import org.mockito.Mockito;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Arrays;

public class PageInterceptorTests {
    @Test
    public void 参数是集合类型() {
        MybatisSql sql = new MysqlSql(getContext());
        try {
            sql.stmtPager(new PageSet(), "PageInterceptorTests_1", new Object() {
                public Integer[] list = {1, 2, 3};
            });
        } catch (IndexOutOfBoundsException e) {

        }
    }

    private Connection getConnection() {
        try {
            Connection conn = Mockito.mock(Connection.class);
            PreparedStatement ps = Mockito.mock(PreparedStatement.class);
            ResultSet rs = Mockito.mock(ResultSet.class);
            ResultSetMetaData meta = Mockito.mock(ResultSetMetaData.class);
            Mockito.when(ps.getResultSet()).thenReturn(rs);
            Mockito.when(ps.executeQuery()).thenReturn(rs);
            Mockito.when(rs.getMetaData()).thenReturn(meta);
            Mockito.when(conn.prepareStatement(Mockito.anyString())).thenReturn(ps);
            return conn;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private SqlSessionFactory getFactory() {
        DataSource ds = Mockito.mock(DataSource.class);
        try {
            Connection conn = getConnection();
            Mockito.when(ds.getConnection()).thenReturn(conn);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        TransactionFactory transactionFactory = new JdbcTransactionFactory();
        Environment environment = new Environment("baseFx/tests", transactionFactory, ds);
        Configuration configuration = new Configuration(environment);
        configuration.setLogImpl(org.apache.ibatis.logging.stdout.StdOutImpl.class);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(configuration);
        InputStream stream = ResourceUtils.getStream("/baseFx/tests/database/mybatis/TestSql.xml");
        XMLMapperBuilder mapBuilder = new XMLMapperBuilder(stream, factory.getConfiguration(), null, configuration.getSqlFragments());
        mapBuilder.parse();
        return factory;
    }

    public MybatisContext getContext() {
        DataSource ds = Mockito.mock(DataSource.class);
        try {
            Connection conn = getConnection();
            Mockito.when(ds.getConnection()).thenReturn(conn);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        MybatisContext context = new MybatisContext("baseFx/tests", ds);
        context.loadXmlMapper(Arrays.asList("/sqlMapper/TestSql.xml"));
        return context;
    }
}
